package com.api.controller;

import cn.hutool.core.util.StrUtil;
import com.api.entity.*;
import com.api.entity.table.MenusTableDef;
import com.api.log.Log;
import com.api.mapper.MenuRightMapper;
import com.api.mapper.MenusMapper;
import com.api.mapper.RolesMapper;
import com.api.utils.ParamsUtils;
import com.api.utils.Result;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.api.entity.table.MenuRightTableDef.MENU_RIGHT;
import static com.api.entity.table.MenusTableDef.MENUS;
import static com.api.entity.table.RoleRightTableDef.ROLE_RIGHT;
import static com.api.entity.table.RolesTableDef.ROLES;
import static com.api.entity.table.UserDeptTableDef.USER_DEPT;
import static com.api.entity.table.UserRoleTableDef.USER_ROLE;
import static com.api.entity.table.UserTableDef.USER;
import static com.mybatisflex.core.query.QueryMethods.case_;

/**
 * @Author: yangsf
 * @CreateDate: 2024/9/24
 */

@Slf4j
@RestController
@RequestMapping("/roles")
public class RolesController extends BaseController {

    @Autowired
    RolesMapper rolesMapper;
    @Autowired
    MenuRightMapper menuRightMapper;
    @Autowired
    MenusMapper menusMapper;

    @Log("获取角色列表")
    @RequestMapping("/getList")
    public Result getList(@RequestParam Map<String,Object> params){
        Long loginUserId = getUserId();
        QueryWrapper qw = new QueryWrapper();
        qw.select(ROLES.ALL_COLUMNS,USER.as("cn").USER_NAME.as("createName"),USER.as("un").USER_NAME.as("updateName"))
        .leftJoin(USER.as("cn")).on(USER.as("cn").ID.eq(ROLES.CREATE_ID))
        .leftJoin(USER.as("un")).on(USER.as("un").ID.eq(ROLES.UPDATE_ID))
        .where(ROLES.STATUS.gt(0));
        if(params.containsKey("nameKeyword") && null != params.get("nameKeyword") && !StringUtils.isEmpty(params.get("nameKeyword"))){
            String nameKeyword = params.get("nameKeyword").toString();
            qw.and(ROLES.ROLE_NAME.like(nameKeyword));
        }
        if(params.containsKey("status") && null != params.get("status") && !StringUtils.isEmpty(params.get("status"))){
            Integer status = Integer.parseInt(params.get("status").toString());
            qw.and(ROLES.STATUS.eq(status));
        }
        //接口的数据权限: 1.全部数据  2.部门数据 3.个人数据 0.无权限
        int mLevel = getMenuRight("/user/getList");
        if(mLevel == 0){
            return Result.notRight();
        }
        //2.部门数据
        else if(mLevel == 2){
            Long deptId = getDeptId();
            if(null == deptId){
                return Result.err("未获取到部门信息, 请联系管理员");
            }
            qw.and(USER_DEPT.DEPT_ID.eq(deptId));
        }
        //3.个人数据
        else if(mLevel == 3){
            qw.and(USER.ID.eq(loginUserId).or(USER.CREATE_ID.eq(loginUserId)));
        }
        Page page = ParamsUtils.toPage(params);
        Page<Roles> pages = rolesMapper.paginate(page,qw);
        return Result.ok(pages);
    }

    @Log("获取系统角色列表(不分页)")
    @RequestMapping("/getRoles")
    public Result getRoles(){
        QueryWrapper qw = new QueryWrapper();
        qw.select(ROLES.ALL_COLUMNS).where(ROLES.STATUS.gt(0));
        List<Roles> list =rolesMapper.selectListByQuery(qw);
        return Result.ok(list);
    }


    @Log("校验角色名称")
    @RequestMapping("/checkRoleName")
    public Result checkRoleName(Long id, String roleName){
        if(StrUtil.isBlank(roleName)){
            return Result.err("角色名称必填");
        }
        Roles roles = Roles.create().select(ROLES.ALL_COLUMNS).where(ROLES.STATUS.eq(1)).and(ROLES.ROLE_NAME.eq(roleName)).one();
        if(null != roles){
            if(null == id || null != id && id.intValue() != roles.getId().intValue()){
                return Result.err("系统存在当前角色名称");
            }
        }
        return Result.ok();
    }

    @Log("保存角色信息")
    @RequestMapping("/save")
    public Result save(@RequestBody Roles roles){
        boolean isAdd = null == roles.getId()?true:false;
        Long userId = getUserId();
        if(isAdd){
            roles.setStatus(1);
            roles.setRoleType(50);
            roles.setCreateId(userId);
        }
        roles.setUpdateId(userId);
        boolean b = roles.saveOrUpdate();
        if(b){
            return Result.ok();
        }
        return Result.err();
    }


    @Log("删除角色")
    @RequestMapping("/delRole")
    public Result delRole(Long  id){
        if(null == id){
            return Result.err("未获取到角色ID");
        }
        Roles role = Roles.create()
                .where(ROLES.ID.eq(id)).and(ROLES.STATUS.eq(1))
                .one();
        if(null == role){
            return Result.err("未获取到角色信息");
        }
        List<UserRole> list = UserRole.create().where(USER_ROLE.ROLE_ID.eq(id)).list();
        if(list.size()>0){
            return Result.err("当前角色下，有关联用户，请先解除关联");
        }
        boolean b = Roles.create()
                .setId(id)
                .setStatus(0)
                .updateById();
        if(b){
            return Result.ok();
        }
        return Result.err();
    }

    @Log("设置角色菜单权限")
    @RequestMapping("/setRoleRight")
    public Result setRoleRight(@RequestBody Map<String,Object> params){
        if(null == params){
            return Result.err("未获取到参数信息");
        }
        Long rellId = null;
        List<Integer> menuIds = null;
        if(params.containsKey("rellId") && null != params.get("rellId") && !StringUtils.isEmpty(params.get("rellId").toString())){
            rellId = Long.parseLong(params.get("rellId").toString());
        }
        if(null == rellId){
            return Result.err("未获取到角色信息");
        }
        if(params.containsKey("menuIds") && null != params.get("menuIds") && !StringUtils.isEmpty(params.get("menuIds").toString())){
            menuIds = (List<Integer>) params.get("menuIds");
        }
        QueryWrapper qw = new QueryWrapper();
        qw.select(MENU_RIGHT.ALL_COLUMNS)
                .where(MENU_RIGHT.KIND.eq(1))
                .and(MENU_RIGHT.RELL_ID.eq(rellId));
        List<MenuRight> mrs = menuRightMapper.selectListByQuery(qw);
        int i = 0;
        if(mrs.size()>0){
            //MenuRight menuRight = MenuRight.create().setStatus(0);
            List<Long> ids = mrs.stream().map(e -> e.getId()).collect(Collectors.toList());
            i = menuRightMapper.deleteBatchByIds(ids);
        }
        else{
            i = 1;
        }
        if(i>0){
            if(null != menuIds && menuIds.size()>0){
                Long userId = getUserId();
                List list = new ArrayList();
                for (Integer reId : menuIds){
                    MenuRight mr = MenuRight.create()
                            .setKind(1)
                            .setRellId(rellId)
                            .setMenuId(reId.longValue())
                            .setStatus(1)
                            .setCreateId(userId)
                            .setUpdateId(userId);
                    list.add(mr);
                }
                menuRightMapper.insertBatch(list);
            }
            return Result.ok();
        }
        return Result.err();
    }

    @Log("设置角色的数据权限")
    @RequestMapping("/setRoleDataRight")
    public Result setRoleDataRight(Long roleId, Long menuId, Integer kind){
        if(null == roleId){
            return Result.err("未获取到角色信息");
        }
        if(null == menuId){
            return Result.err("未获取到菜单信息");
        }
        if(null == kind){
            return Result.err("未获取到权限信息");
        }
        Long userId = getUserId();
        RoleRight roleRight = RoleRight.create().select(ROLE_RIGHT.ALL_COLUMNS)
                .where(ROLE_RIGHT.STATUS.eq(1))
                .and(ROLE_RIGHT.ROLE_ID.eq(roleId))
                .and(ROLE_RIGHT.MENU_ID.eq(menuId))
                .one();
        if(null != roleRight){
            roleRight.setStatus(1);
            roleRight.setMenuId(menuId);
            roleRight.setKind(kind);
        }
        else{
            roleRight = RoleRight.create()
                    .setRoleId(roleId)
                    .setMenuId(menuId)
                    .setKind(kind)
                    .setStatus(1)
                    .setCreateId(userId);
        }
        roleRight.setUpdateId(userId);
        boolean b = roleRight.saveOrUpdate();
        if(b) {
            return Result.ok();
        }
        return Result.err();
    }

    @Log("分配菜单权限, 根据角色ID, 获取角色被赋权的功能菜单(menuType==2)")
    @RequestMapping("/getRoleMenus")
    public Result getRoleMenus(Long roleId){
        if(null == roleId){
            return Result.err("未获取到角色信息");
        }
        List<Menus> menus = new ArrayList<Menus>();
        List<Long> ids = MenuRight.create()
                .select(
                    case_().when(MENUS.MENU_TYPE.eq(2)).then(MENU_RIGHT.MENU_ID).else_(MENUS.PARENT_ID).end().as("ids")
                )
                .leftJoin(MENUS).on(MENUS.ID.eq(MENU_RIGHT.MENU_ID))
                .where(MENU_RIGHT.STATUS.eq(1))
                .where(MENUS.STATUS.eq(1))
                .and(MENUS.MENU_TYPE.in(2,3))
                .and(MENU_RIGHT.RELL_ID.eq(roleId))
                .listAs(Long.class);
        if(ids.size() > 0){
            QueryWrapper qw = QueryWrapper.create();
            qw.select(MENUS.ID, MENUS.TITLE, MENUS.MENU_TYPE, ROLE_RIGHT.KIND)
            .from(MENUS)
            .leftJoin(ROLE_RIGHT).on(ROLE_RIGHT.STATUS.eq(1).and(ROLE_RIGHT.MENU_ID.eq(MENUS.ID)).and(ROLE_RIGHT.ROLE_ID.eq(roleId)))
            .where(MENUS.KIND.eq(1))
            .and(MENUS.STATUS.eq(1))
            .and(MENUS.MENU_TYPE.eq(2))
            .and(MENUS.ID.in(ids))
            .orderBy(MENUS.SORT_NUM,true);
            menus = menusMapper.selectListByQuery(qw);
        }
        return Result.ok(menus);
    }

    @Log("分配菜单权限, 根据角色ID, 获取角色被赋权的菜单ID(menuType in (2,3))")
    @RequestMapping("/getRoleMenuIds")
    public Result getRoleMenuIds(Long roleId){
        if(null == roleId){
            return Result.err("未获取到角色ID");
        }
        List<String> menuIds = MenuRight.create()
                .select(MENU_RIGHT.MENU_ID)
                .leftJoin(MENUS).on(MENUS.ID.eq(MENU_RIGHT.MENU_ID))
                .where(MENU_RIGHT.STATUS.in(1, 2))
                .and(MENU_RIGHT.KIND.eq(1))
                .and(MENUS.STATUS.eq(1))
                .and(MENUS.KIND.eq(1))
                .and(MENUS.MENU_TYPE.in(2,3))
                .and(MENU_RIGHT.RELL_ID.eq(roleId))
                .listAs(String.class);
        return Result.ok(menuIds);
    }


    @Log("获取角色的数据权限")
    @RequestMapping("/getRoleDataRight")
    public Result getRoleDataRight(Long roleId){
        if(null == roleId){
            return Result.err("未获取到角色信息");
        }
        List<RoleRight> list = RoleRight.create().select(ROLE_RIGHT.ALL_COLUMNS)
                .where(ROLE_RIGHT.STATUS.eq(1))
                .and(ROLE_RIGHT.ROLE_ID.eq(roleId))
                .list();
        return Result.ok(list);
    }

}
